package aplug;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.os.Handler;
import android.support.multidex.MultiDex;

import com.amap.api.maps.MapsInitializer;

import org.changs.aplug.AplugApp;
import org.changs.aplug.AplugManager;
import org.changs.aplug.utils.NetworkUtils;
import org.changs.aplug.utils.ProcessUtils;
import org.changs.control.event.NetConnectEvent;
import org.changs.control.event.RemoteIpEvent;
import org.changs.control.event.RequestMsgEvent;
import org.changs.control.event.WifiApStateEvent;
import org.changs.control.push.PushClient;
import org.changs.control.service.MessageService;
import org.changs.control.ui.offlinemap.OfflineMapPresenter;
import org.changs.servlet.IOUtils;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import javax.inject.Inject;

import aplug.data.db.PushMsgHelper;
import aplug.data.prefs.PreferencesHelper;
import aplug.di.DaggerAppComponent;
import dagger.Lazy;
import dagger.android.AndroidInjector;
import dagger.android.support.DaggerApplication;
import io.reactivex.plugins.RxJavaPlugins;
import io.vov.vitamio.Vitamio;
import timber.log.Timber;

/**
 * Created by yincs on 2017/8/30.
 */

public class AppManagerImpl extends AplugApp implements AppManager {

    @Inject PreferencesHelper mPreferencesHelper;
    @Inject PushMsgHelper mPushMsgHelper;
    @Inject OfflineMapPresenter mOfflineMapPresenter;
    @Inject Lazy<PushClient> mPushClient;

    private RemoteIPOpt mRemoteIPOpt = new RemoteIPOpt();
    private Handler mHandler = new Handler();

    @Override
    protected void attachBaseContext(Context base) {
        super.attachBaseContext(base);
        MultiDex.install(base);
    }

    @Override
    public void onTerminate() {
        super.onTerminate();
        AplugManager.get().onTerminate();
    }

    @Override
    protected AndroidInjector<? extends DaggerApplication> applicationInjector() {
        return DaggerAppComponent.builder().application(this).build();
    }

    @Override
    public Context getContext() {
        return this;
    }

    @Override
    public PreferencesHelper getPreferencesHelper() {
        return mPreferencesHelper;
    }

    @Override
    public PushMsgHelper getPushMsgHelper() {
        return mPushMsgHelper;
    }

    @Override
    public String getRemoteIp() {
        return mRemoteIPOpt.mRemoteIp;
    }

    @Override
    public void disRemoteIp() {
        mRemoteIPOpt.mRemoteIp = null;
        EventBus.getDefault().post(new RemoteIpEvent(null));
    }

    @Override
    public Handler getHandler() {
        return mHandler;
    }

    @Override
    public void onCreate() {
        initMap();
        initVitamio();
        super.onCreate();
    }

    @Override
    protected void firstCreate() {
        AplugManager.get().onCreate(new AplugManager
                .Config(this)
                .debug());

        RxJavaPlugins.setErrorHandler(throwable -> {
            Timber.d("RxJavaPlugins ErrorHandle throwable = [" + throwable + "]");
            throwable.printStackTrace();
        });

        if (ProcessUtils.isDefaultProcess(this)) {
            initService();
            initReceiver();
            initTimer();
            initPush();
        }
    }

    private void initTimer() {
        mHandler.post(mRemoteIPOpt);
    }

    private void initService() {
        startService(new Intent(this, MessageService.class));
    }

    private void initReceiver() {
        final IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(IOUtils.Action.CONNECT);
        intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
        intentFilter.addAction("android.net.wifi.WIFI_AP_STATE_CHANGED");
        registerReceiver(new MyReceiver(), intentFilter);
    }

    private void initMap() {
        MapsInitializer.sdcardDir = AppConfig.getMapRootFile().getAbsolutePath();
    }

    private void initVitamio() {
        Vitamio.isInitialized(this);
    }

    /**
     * 消息 推送
     */
    private void initPush() {
        mPushClient.get().register();
    }


    private class MyReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
//            Timber.d("MyReceiver action = " + action);
//            Timber.d("MyReceiver intent = " + intent);
            if (ConnectivityManager.CONNECTIVITY_ACTION.equals(action)) {
                mRemoteIPOpt.removeRemoteIp();
                boolean isConnected = NetworkUtils.isConnected(AppManagerImpl.this);
                boolean isWifi = false;
                if (isConnected) {
                    isWifi = NetworkUtils.isWifiConnected(context);
                }
                EventBus.getDefault().post(new NetConnectEvent(isConnected, isWifi));
                if (isConnected) {//有网络
                    mPushClient.get().register();
                }
            } else if ("android.net.wifi.WIFI_AP_STATE_CHANGED".equals(action)) {
                mRemoteIPOpt.removeRemoteIp();
                //便携式热点的状态为：10---正在关闭；11---已关闭；12---正在开启；13---已开启
                int state = intent.getIntExtra("wifi_state", 0);
                Timber.d("wifi热点 state = " + state);
                EventBus.getDefault().post(new WifiApStateEvent(state));
            }
        }

    }

    private class RemoteIPOpt implements Runnable {
        private String mRemoteIp;
        private long mRemoteIpReceiverTime;

        {
            EventBus.getDefault().register(this);
        }

        @Subscribe(threadMode = ThreadMode.MAIN)
        public void onEvent(RequestMsgEvent event) {
            if (IOUtils.Action.CONNECT.equals(event.action)) {
                String remoteIp = event.data;
                boolean isConnected = mRemoteIp != null;
                mRemoteIPOpt.mRemoteIp = remoteIp;
                mRemoteIPOpt.mRemoteIpReceiverTime = System.currentTimeMillis();
                if (!isConnected) {
                    EventBus.getDefault().post(new RemoteIpEvent(remoteIp));
                    mHandler.postDelayed(this, 1000);
                }
            }
        }

        private void removeRemoteIp() {
            mRemoteIp = null;
            EventBus.getDefault().post(new RemoteIpEvent(null));
            mHandler.removeCallbacks(this);
        }

        @Override
        public void run() {
            if (mRemoteIp != null && System.currentTimeMillis() - mRemoteIpReceiverTime > 5000) {
                removeRemoteIp();
            } else {
                mHandler.removeCallbacks(this);
                mHandler.postDelayed(this, 1000);
            }
        }
    }
}
